home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 051-075 / disk_075 / comm / keyboard.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  11KB  |  345 lines

  1. /*  Comm keyboard routines */
  2.  
  3. #define  KEYBOARD 1
  4. #include "globals.h"
  5.  
  6. extern  int capture;
  7.  
  8. #define ERR    "\nKEY MACRO error."
  9. #define KEYERR -1
  10. #define NOMEM  -2
  11. #define OFFSET FN1                  /* convert to cardinal number */
  12.  
  13. static UBYTE *string;               /* temp string pointer */
  14. static UBYTE workbuff[ SECSIZ ];    /* keyboard macro work area */
  15.  
  16. #define ENTRIES  112                /* keys on keyboard */
  17.  
  18. UBYTE  toasc(code,qual)
  19. USHORT qual,code;
  20. {
  21.    static USHORT  caps = FALSE;
  22.    UBYTE  c;
  23.    static UBYTE nosh[ ENTRIES ] = {
  24.                     '`','1','2','3','4','5','6','7',
  25.                     '8','9','0','-','=',SLH,UND,'0',
  26.                     'q','w','e','r','t','y','u','i',
  27.                     'o','p','[',']',UND,'1','2','3',
  28.                     'a','s','d','f','g','h','j','k',
  29.                     'l',';',APS,UND,UND,'4','5','6',
  30.                     UND,'z','x','c','v','b','n','m',
  31.                     ',','.','/',UND,'.','7','8','9',
  32.                     ' ',BKS,TAB,ENT,RET,ESC,DEL,UND,
  33.                     UND,UND,'-',UND,CUP,CDN,CFW,CBK,
  34.                     FN1,FN2,FN3,FN4,FN5,FN6,FN7,FN8,
  35.                     FN9,F10,UND,UND,UND,UND,UND,HLP,
  36.                     LSH,RSH,CAP,CTL,LAL,RAL,LAM,RAM,
  37.                     LMB,RMB,MMB,UND,UND,UND,UND,UND
  38.                   };
  39.  
  40.    static UBYTE shift[ ENTRIES ] = {
  41.                     '~','!','@','#','$','%','^','&',
  42.                     '*','(',')','_','+','|',UND,'0',
  43.                     'Q','W','E','R','T','Y','U','I',
  44.                     'O','P','{','}',UND,'1','2','3',
  45.                     'A','S','D','F','G','H','J','K',
  46.                     'L',':','"',UND,UND,'4','5','6',
  47.                     UND,'Z','X','C','V','B','N','M',
  48.                     '<','>','?',UND,'.','7','8','9',
  49.                     ' ',BKS,TAB,ENT,RET,ESC,DEL,UND,
  50.                     UND,UND,'-',UND,CUP,CDN,CFW,CBK,
  51.                     SF1,SF2,SF3,SF4,SF5,SF6,SF7,SF8,
  52.                     SF9,S10,UND,UND,UND,UND,UND,SHH,
  53.                     LSH,RSH,CAP,CTL,LAL,RAL,LAM,RAM,
  54.                     LMB,RMB,MMB,UND,UND,UND,UND,UND
  55.                   };
  56.  
  57.    switch(code)
  58.     {
  59.       case  98:   caps   = TRUE;  break;      /* caps lock pressed  */
  60.       case 226:   caps   = FALSE; break;      /* caps lock released */
  61.     }
  62.  
  63.  
  64.    if(code < ENTRIES)
  65.     {
  66.        c = nosh[ code ];                       /* default lower case */
  67.        if(qual & 0x40)                         /* left amiga */
  68.        {
  69.          switch(c)
  70.          {
  71.             case 'p':   return TOGPRT;         /* Toggle printer */
  72.             case 'c':   return TOGCAP;         /* Toggle capture buffer */
  73.             case 's':   return TOGSCR;
  74.          }
  75.        }
  76.        if(qual & 3)
  77.             return (shift[ code ]);            /* shift key down     */
  78.        if( isalpha(c) )                        /* control or CAPS?   */
  79.          {
  80.           if(qual & 8)
  81.             return(UBYTE)(shift[ code ] - '@');/* control down ?     */
  82.                                                /* make it a control  */
  83.           if ( caps )                          /* caps lock down     */
  84.             return ( shift[ code ]);           /* make it upper case */
  85.          }
  86.        return (c);
  87.     }
  88.    return (UND);                               /* for release code   */
  89. } /* end of routine */
  90.  
  91. /*
  92.    Expand keyboard macros.  Control characters are sent by prefixing the
  93.    ASCII equiv. with ^.  Ex, control C is ^C, control X is ^X.
  94.    Also translates C type slash characters like \t, \r and \n.
  95.    In this implimentation, \n and \r generate the RETURN code (0xD).
  96.    Also, \w produces a 500 millisecond delay and \l produces a line break.
  97. */
  98. void expand_macro(key)
  99. char key;
  100. {
  101.    key -= OFFSET;                        /* F1 becomes offset zero */
  102.    string = keymacro[ key ];             /* point to definition */
  103.    if(string == NULL) return;            /* return if not defined */
  104.    sendout( string );
  105. }
  106.  
  107. /* do the actual expansion.  Send the characters to the modem */
  108.  
  109. sendout(str)
  110. UBYTE *str;
  111. {
  112.    static UBYTE macro[] = "00000000000000000000";
  113.    unsigned  key;
  114.    UBYTE     c;
  115.  
  116.    while( c = *str++ )                    /* do until end of string */
  117.     {
  118.       if( c == '^') {                     /* control character ^? */
  119.          if((c = *str++) == '^')
  120.             break;
  121.          else c = toupper(c)- 0x40;       /* convert only valid chars */
  122.       }
  123.       else if( c == '\\')                /* have an escape character? */
  124.          switch( c = tolower(*str++))    /* yes, get next character */
  125.          {
  126.             case 'r': c = '\r'; break;   /* C equivilents */
  127.             case 'n': c = '\r'; break;
  128.             case 't': c = '\t'; break;
  129.             case 'f': c = '\f'; break;
  130.             case 'b': c = '\b'; break;
  131.                                          /* now my own */
  132. /*
  133.             case 'p':
  134.                       c = *str++;
  135.                       if( c == '^')
  136.                           c = toupper(*str++) - 0x40;
  137.                       do {
  138.                             key = readchar(10,0);
  139.                             if( key == TIMEOUT ) break;
  140.                       } while ( (tolower(key) != tolower(c)) );
  141.                       continue;
  142. */
  143.             case 'l':                    /* line break */
  144.                       SendBreak(); continue;
  145.             case 'w':                    /* delay 1/2 second */
  146.                       Delay(25L);continue;
  147.             case 'm':                    /* expand another macro */
  148.                       key = atoi(str);
  149.                       while(isdigit(*str))
  150.                            str++;
  151.                       if( (key > 0) && (key <= KEYMACS) )
  152.                       {
  153.                         if(macro[ key -1 ] != '0')
  154.                         {
  155.                            emits_rx("\nKEY MACRO RECURSION not allowed -- or desired!\n");
  156.                            continue;
  157.                         }
  158.                         macro[ key-1 ] = '1';
  159.                         expand_macro( key - 1 + OFFSET );
  160.                         macro[ key-1 ] = '0';
  161.                       }
  162.                       continue;
  163.  
  164.             case '\\':break;
  165.  
  166.             default:                     /* was really a \ character alone */
  167.                str--;                    /* adjust string pointer */
  168.                c = '\\';                 /* and send the \ */
  169.           }
  170.       if(halfduplex)
  171.         emit_rx( c );
  172.       if(split_screen)
  173.         emit_tx( c );                    /* echo it to the user */
  174.       if (capture && capton)             /* capturing data to disk file? */
  175.          if (isprint(c)) buffer_it(c);
  176.       sendchar( c );
  177.     }
  178. }
  179.  
  180.  
  181. /*  open keyboard macro file.  Return 0 if not found, else return # of
  182.      macros in the library.
  183.     allocate memory for the macros and copy them to memory.
  184. */
  185. int Init_keymacros()
  186. {
  187.    USHORT i;
  188.    for(i = 0; i < KEYMACS; i++)        /* init array of pointers */
  189.       keymacro[i] = NULL;
  190.    Load_keymacros(commkeys);
  191. }
  192.  
  193. Load_keymacros(name)
  194. UBYTE *name;
  195. {
  196.    extern UBYTE *malloc();
  197.    int index, i;
  198.    FILE *inp;
  199.    UBYTE temp[42], *file, p[42];
  200.  
  201.    if(*name == NULL) return;           /* no name given */
  202.    strcpy(p,name);
  203.  
  204.    i = strlen(p);
  205.    while(--i)                          /* remove trailing blanks from */
  206.      if(p[i] != ' ') break;            /* filename */
  207.  
  208.    if(i == 0) return;                  /* blank name given */
  209.    p[++i] = NULL;
  210.  
  211.    index = 0;
  212.  
  213.    strcpy(temp,install.DefDir);
  214.    strcat(temp,p);
  215.  
  216.    file = name;                        /* try to open macro file */
  217.    if(( inp = fopen(p,"r")) == NULL)   /* check default directory */
  218.    {
  219.      file = temp;
  220.      if((inp = fopen(temp,"r")) == NULL) /* then SYS: directory */
  221.         return NULL;
  222.    }
  223.    strcpy(commkeys,file); 
  224.    Free_keymacros();                   /* free any memory allocated */
  225.  
  226.    while (fgets(workbuff,SECSIZ,inp))           /* do until end of file */
  227.    {
  228.         if(strlen(workbuff) < 3) continue;      /* ignore short lines   */
  229.         workbuff[ strlen(workbuff)-1 ] = NULL;  /* kill trailing \n     */
  230.         if((index = Add_keymacro()) == NOMEM)   /* no memory left       */
  231.         {
  232.           emits_rx("\nOut of memory\n");
  233.           break;
  234.         }
  235.    }
  236.    fclose(inp);
  237.    return index;
  238. }
  239.  
  240. /* Save key macros to named file */
  241. Save_keymacros(name)
  242. UBYTE *name;
  243. {
  244.    FILE   *out;
  245.    USHORT i;
  246.    int    error;
  247.  
  248.    if((out = fopen(name,"w")) == NULL)
  249.    {
  250.       sprintf(sbuff,"\nCan't open file %s\n",name);
  251.       emits_rx(sbuff);
  252.       return NULL;
  253.    }
  254.    for(i = 0; i < KEYMACS; i++)
  255.       if( keymacro[ i ] )
  256.          fprintf(out,"%c%d%s\n",
  257.                        (i > 9) ? 'S' : 'F',
  258.                        (i > 9) ? i-9 : i+1,
  259.                        keymacro[ i ]);
  260.    error = ferror(out);
  261.    fclose( out );
  262.    if( error )
  263.    {
  264.       emits_rx("Error during file write\n");
  265.       return NULL;
  266.    }
  267.    return OK;
  268. }
  269.  
  270. /*
  271.    Return memory allocated for all key macros
  272. */
  273. Free_keymacros()
  274. {
  275.    int i;
  276.    for( i=0; i < KEYMACS; i++)
  277.      free_macro(i);
  278. }
  279.  
  280. /*
  281.    Return memory allocated for single macro
  282. */
  283. free_macro(num)
  284. int num;
  285. {
  286.    if(keymacro[ num ])
  287.    {
  288.       free(keymacro[ num ]);
  289.       keymacro[ num ] = NULL;
  290.    }
  291. }
  292. /*
  293.    Bring up the ASCII input window for macro entry
  294. */
  295. Edit_keymacro()
  296. {
  297.    workbuff[0] = NULL;
  298.    getstring(" USE","new key macro",workbuff,SECSIZ);
  299. }
  300.  
  301. /*
  302.    Parse macro string and add it to macro list
  303. */
  304. Add_keymacro()
  305. {
  306.   int index, shift;
  307.  
  308.   if(*workbuff == NULL) return NULL;
  309.   string = &workbuff[2];
  310.   
  311.   if( (toupper(*workbuff) != 'F' && toupper(*workbuff) != 'S') ||
  312.              !isdigit(workbuff[1]))
  313.    {                    /* line doesn't start with Fn or Sn */
  314.      emits_rx(ERR);
  315.      sprintf(sbuff,"\nExpected Fnn or Snn but read:  %10s\n",workbuff);
  316.      emits_rx(sbuff);
  317.      return KEYERR;
  318.    }
  319.   shift = (toupper(*workbuff) == 'F') ? 0 : 10;
  320.  
  321.   index = workbuff[1] - '1';       /* index is 0 to 9 */
  322.   if(workbuff[1] == '1')
  323.     if(workbuff[2] == '0')
  324.     {                              /* F10 is ok */
  325.       string++;                    /* skip past extra 0 */
  326.       index = 9;                   /* make index 10 - 1 */
  327.     }
  328.  
  329.   index += shift;                  /* account for shift Fnn key */
  330.   free_macro(index);               /* if already allocated, deallocate it */
  331.  
  332.   if(*string == NULL) return NULL;
  333.   keymacro[index] = malloc(strlen(string));
  334.   if(keymacro[index])             /* if allocation succeeded, copy string */
  335.     strcpy(keymacro[index],string);
  336.   else                            /* else, can't do it */
  337.    {
  338.      sprintf(sbuff,"\nCan't allocate memory for key macro F%d\n", index+1);
  339.      emits_rx(sbuff);
  340.      return NOMEM;
  341.    }
  342.   return index;
  343. }
  344.  
  345.